define(function(require, exports, module) {
	/**
	 * 检查密码强度。
	 * @return {Number} 0/1/2/3分别代表无效/差/一般/强
	 */
	function level(s){
		var i = 0;
		password.length > 6 			&& i++;	// 足够的长度。
		/[a-z]/ig.test(password)		&& i++;	// 有字母。
		/\d/g.test(password)			&& i++;	// 有数字。
		/(.[^a-z0-9])/ig.test(password)	&& i++;	// 有非字母、非数字以外的字符。

		return i;
	}

	// 密码两组输入框分别要是 class="password_1" class="password_2"。

	// el: element
	var passwordVaild = {
		init : function(form){
			var password_1 = form.querySelector('.password_1'),
				password_2 = form.querySelector('.password_2'),
				tips_1	   = form.querySelector('.tips_1'),
				tips_2	   = form.querySelector('.tips_2'),
				// info	   = form.querySelector('.info'),
				state_1    = form.querySelector('.state_1'),
				state_2    = form.querySelector('.state_2');

			var _onFocus = onFocus.bind(this), _onBlur = onBlur.bind(this);
			
			password_1.addEventListener('focus', _onFocus);
			password_2.addEventListener('focus', _onFocus);
			password_1.addEventListener('blur', _onBlur);
			password_2.addEventListener('blur', _onBlur);

			this.password_1 = password_1;
			this.password_2 = password_2;

			this.msg = { // 设置一组变量记忆 UI
				1 : {
					tips : tips_1, state : state_1
				},
				2 : {
					tips : tips_2, state : state_2
				}
			}
		}
	};

	function onFocus(e) {
		var el = e.target, id = el.className.match(/password_(\d)/), id = id[1];
		
		this.msg[id].tips.style.display = 'inline';	
		this.msg[id].state.style.display = 'none';		
	}

	function onBlur(e) {
		var el = e.target, err = isPass(el), id = el.className.match(/password_(\d)/), id = id[1];

		// this.msg[id].tips.style.display = 'none';

		if(err === true){
			el.style.borderColor = 'lightgrey';
		}else{
			el.style.borderColor = 'red';
			// this.msg[id].state.style.display = 'inline';
			this.msg[id].state.innerHTML = err;
		}
		if(id == 2 && (this.password_1.value != this.password_2.value)){
			// this.msg[id].state.style.display = 'inline';
			this.msg[id].state.innerHTML = '两次密码不一致！';
		}
	}

	function isPass(el){
		var len = el.value.length;

		if(!len){
			return "未输入密码";
		}else if(len >= 6 && len <= 12){
			return true;
		}else if(len < 6){
			return "密码长度太短";
		}else if(len > 12){
			return "密码长度太长";
		}

		return '未知错误！';
	}

	exports.passwordVaild = passwordVaild;

    function onFail(el){
         el.style.border = "1px solid red";
	}

	var stateInfoTpl = '<strong class="arrow_1"></strong><strong class="arrow_2"></strong>';

	function toggleDisplay(e){
		// 获取焦点时显示提示消息
		var input = e.parentNode ? e : e.target; // 参数 e 既可为 Event 事件对象，也可以为 input/textarea 元素
		if (input.tagName == 'INPUT' || input.tagName == 'TEXTAREA'){

		}else{
			throw '非输入元素，监听 focus 事件何用？';
		}

		if(input.getAttribute('noCheck') != null || input.type == 'hidden' || input.type == 'submit')
			return true; /* 某些input 豁免 */
		
		// 约定兄弟元素为消息节点。采用 相对 位置 定位元素
		var tips = input.parentNode.querySelector('.tips'), state = input.parentNode.querySelector('.state');

		var err;
		// 如果为失去事件，则验证输入框（我们把 onBlur 和 onFocus 写在同一个 时间处理器 中）
		if(e.type == 'focus'){
			tips.style.display  = window.getComputedStyle(tips).display == 'none' ? 'inline' : 'none';
			state.style.display = 'none';

			input.removeCls('errHighlight');
		}else if(e.type == 'blur' || e.parentNode/* 为元素，要作检查的意思 */){
			err = checkErr(input);
			if (err != true){
				state.innerHTML = stateInfoTpl + err;// 有错误
				input.addCls('errHighlight');
			}else{
				state.innerHTML = stateInfoTpl + '√';// 显示 ok
				input.removeCls('errHighlight');
			}
			tips.style.display = 'none';
			state.style.display = 'inline';
		}


		return err;
		
	}

	exports.toggleDisplay = toggleDisplay;

	// 检测流程：是否有填/长度/类型 input:element
	function checkErr(input){
		var value = input.value, value = value.replace(/(^\s*)|(\s*$)/g, "");

		// 是否已填检测
		var isRequire = input.getAttribute('requiredField');
		if (isRequire != null && value == ''){
			return '亲，此为必填项';
		}

		// 最小长度检测
		var minLength = input.getAttribute('minLength');
		if (minLength != null && !(new RegExp('.{' + minLength + '}').test(value))){
			// debugger;
			return '亲，输入太少了，得要{0}个字符或以上'.format(minLength);
		}

		// 类型
		var pattern = input.getAttribute('pattern');
		if (pattern != null && !(new RegExp('.{' + pattern + '}').test(value))){
			return '亲，类型不正确';
		}

		return true;
	}

	function checkAllFields(formEl) {
		var errors = [];
        var inputs = formEl.querySelectorAll('input'), textareas = formEl.querySelectorAll('textarea');
        
        (function (els) {
        	var err;
            for (var i = 0, j = els.length; i < j; i++) {
                err = els[i].getAttribute('noCheck') != null /* 某些input 豁免 */ ? true : toggleDisplay(els[i]);
                if(err == true){
                	// 没错
                }else{
                    errors.push({
                    	err : err,
                    	el: els[i]
                    });
                }
            }
            return arguments.callee;
        })(inputs)(textareas);

        return errors;
    }
    exports.checkAllFields = checkAllFields;
});